<?php
/**
 * Created by PhpStorm.
 * User: meng
 * Date: 2023/10/12
 * Time: 10:47
 */

namespace app\admin\service;

use lib\common\CommonService;
use lib\exception\NotFoundException;
use lib\exception\ParamsException;
use model\AdminMenuModel;
use model\AdminPermissionMenuModel;
use model\AdminPermissionModel;
use model\AdminPermissionUserModel;
use think\facade\Db;
use think\Paginator;

class PermissionService extends CommonService
{
    private AdminPermissionModel $adminPermissionModel;
    private AdminPermissionMenuModel $adminPermissionMenuModel;
    private AdminMenuModel $adminMenuModel;

    private AdminPermissionUserModel $adminPermissionUserModel;

    /**
     * @param AdminPermissionModel $adminPermissionModel
     * @param AdminPermissionMenuModel $adminPermissionMenuModel
     * @param AdminMenuModel $adminMenuModel
     * @Param AdminPermissionUserModel $adminPermissionUserModel
     */
    public function __construct (
        AdminPermissionModel     $adminPermissionModel,
        AdminPermissionMenuModel $adminPermissionMenuModel,
        AdminMenuModel           $adminMenuModel,
        AdminPermissionUserModel $adminPermissionUserModel
    ) {
        parent::__construct();
        $this->adminPermissionModel = $adminPermissionModel;
        $this->adminPermissionMenuModel = $adminPermissionMenuModel;
        $this->adminMenuModel = $adminMenuModel;
        $this->adminPermissionUserModel = $adminPermissionUserModel;
    }


    public function getList ($params): Paginator {
        $where = [];
        if (!empty($params['name']) && !empty(trim($params['name']))) {
            $where[] = ['name', 'like', '%' . trim($params['name']) . '%'];
        }
        return $this->adminPermissionModel->where($where)->order('id', 'ASC')->paginate($this->getPageSize());
    }

    public function getAll (): array {
        return $this->adminPermissionModel->order('id', 'ASC')->select()->toArray();
    }

    public function create ($params): void {
        $duplicate = $this->adminPermissionModel->where('name', $params['name'])->find();
        if (!empty($duplicate)) {
            throw new ParamsException('权限组名称重复');
        }
        $this->transaction(function () use ($params) {
            $permission = $this->adminPermissionModel::create($params, $this->adminPermissionModel::ALLOWED_FIELDS);
            $this->adminPermissionMenuModel->saveBatch($permission['id'], $params['menus']);
        });
    }

    public function update ($id, $params): void {
        $permission = $this->get($id);
        $duplicate = $this->adminPermissionModel->where('name', $params['name'])->where('id', '<>', $id)->find();
        if (!empty($duplicate)) {
            throw new ParamsException('权限组名称重复');
        }
        $this->transaction(function () use ($permission, $params) {
            $this->adminPermissionMenuModel->where('permission_id', $permission['id'])->delete();
            $permission->allowField($this->adminPermissionModel::ALLOWED_FIELDS)->save($params);
            $this->adminPermissionMenuModel->saveBatch($permission['id'], $params['menus']);
        });
    }

    public function delete ($id): void {
        $permission = $this->get($id);
        $this->transaction(function () use ($permission) {
            $this->adminPermissionMenuModel->where('permission_id', $permission['id'])->delete();
            $this->adminPermissionUserModel->where('permission_id', $permission['id'])->delete();
            $permission->delete();
        });
    }
    public function read ($id): array {
        $data = $this->get($id)->toArray();
        if ($id == 1) {
            $menus = make(MenuService::class)->menuList(true);
        } else {
            $menus = $this->adminPermissionMenuModel->alias('a')
                ->join([$this->adminMenuModel->getTable() => 'b'], 'a.menu_id = b.id', 'left')
                ->where('a.permission_id', $id)
                ->field('b.*')
                ->select()->toArray();
        }
        $data['menus'] = $menus;
        return $data;
    }

    public function get ($id): AdminPermissionModel {
        $data = $this->adminPermissionModel->find($id);
        if (empty($data)) {
            throw new NotFoundException('权限组不存在');
        }
        return $data;
    }
}
